import java.util.*;

/**
 * 这道题一眼看上去就是一道搜算算法的题，搜索算法就拿两种，dfs，bfs，dfs最全解，bfs最优解，这道题没看出要最优解来，而且不能漏掉
 * 任何一个位置，故选择dfs。
 */
public class A_1{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int n = sc.nextInt();
        int[][] t = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                t[i][j] = sc.nextInt();
            }
        }
        System.out.println(closedIsland(t));
    }
    static boolean flag; //flag用于记录是否遇到边界
    static public int closedIsland(int[][] grid) {
        int num = 0;
        /**
         * 因为要覆盖到所有的陆地，陆地并不一定相连，所有使用嵌套for循环将整个数组进行遍历。
         */
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j]==0){
                    flag = false;//先令flag为false，当dfs搜索到边界时flag转换为true
                    dfs(grid,i,j);
                    if(!flag)//当从来没遇到过地图边界时，flag数值不会发生改变，让num++表示找到了一个封闭岛屿。
                        num++;
                }
            }
        }
        return num;
    }
    static void dfs(int[][] grid,int i ,int j){
        if(i==0||i==grid.length-1||j==0||j==grid[0].length-1){ //遇到地图边界的时候，将全局变量flag设置为true表示这个岛屿并非封闭岛屿。
            flag = true;
            return;
        }
        grid[i][j] = 3;//将已经搜索到的区域设置为非0的值，防止重复搜索
        if (grid[i+1][j]==0)//当下面为陆地时候，向下搜索
            dfs(grid,i+1,j);
        if (grid[i-1][j]==0)//同理，向上搜索
            dfs(grid,i-1,j);
        if (grid[i][j+1]==0)//同理，向左搜索
            dfs(grid,i,j+1);
        if (grid[i][j-1]==0)//同理，向右搜索
            dfs(grid,i,j-1);
        //此搜索函数将覆盖整块陆地，无论陆地是是否为封闭岛屿。
    }
}